/**
 * @file       spin_lock.hpp
 * @author     WMQ
 * @date       2024/12/24
 * @brief      自旋锁
 */

#ifndef SPIN_LOCK_HPP
#define SPIN_LOCK_HPP

#include <atomic>
#include <thread>

class SpinLock
{
public:
    SpinLock() = default;
    ~SpinLock() = default;

    void Lock()
    {
        uint32_t retry_times = 0;
        while (lock_.test_and_set(std::memory_order_acquire)) // 获取锁
        {
            if (++retry_times == MAX_RETRY_TIMES)
            {
                std::this_thread::yield();
                retry_times = 0;
            }
        }
    }

    void Unlock()
    {
        lock_.clear(std::memory_order_release); // 释放锁
    }

    bool TryLock()
    {
        return !lock_.test_and_set(std::memory_order_acquire);
    }

    SpinLock(const SpinLock &) = delete;
    SpinLock &operator=(const SpinLock &) = delete;

private:
    std::atomic_flag lock_ = ATOMIC_FLAG_INIT;
    static const uint32_t MAX_RETRY_TIMES = 3;
};

#endif